﻿using System.Threading.Tasks;
using System.Web;
using System.Web.Mvc;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.EntityFramework;
using Microsoft.Owin.Security;
using MisRepresentantes.Core;
using MisRepresentantes.Core.Utilities;

namespace MisRepresentantes.Web.Controllers
{
    public class AccesoController : Controller
    {
        public AccesoController()
            : this(new UserManager<Ciudadano>(new UserStore<Ciudadano>(new ApplicationDbContext())))
        {
        }

        public AccesoController(UserManager<Ciudadano> userManager)
        {
            UserManager = userManager;
        }

        public UserManager<Ciudadano> UserManager { get; private set; }

        //
        // GET: /Acceso/
        public ActionResult Index()
        {
            return View();
        }

        //
        // GET: /Acceso/
        public ActionResult Registrar()
        {
            return View();
        }

        //
        // POST: /Account/ExternalLogin
        [HttpPost]
        [AllowAnonymous]
        [ValidateAntiForgeryToken]
        public ActionResult Externo(string provider, string returnUrl)
        {
            // Request a redirect to the external login provider
            return new ChallengeResult(provider, Url.Action("ExternoCallback", "Acceso", new { ReturnUrl = returnUrl }));
        }

        //
        // GET: /Acceso/ExternalLoginCallback
        [AllowAnonymous]
        public async Task<ActionResult> ExternoCallback(string returnUrl)
        {
            var loginInfo = await AuthenticationManager.GetExternalLoginInfoAsync();

            if (loginInfo == null)
                return RedirectToAction("Index");

            // Sign in the user with this external login provider if the user already has a login
            var ciudadano = await UserManager.FindAsync(loginInfo.Login);

            if (ciudadano == null)
            {
                // If the user does not have an account, then prompt the user to create an account
                ViewBag.ReturnUrl = returnUrl;
                ViewBag.LoginProvider = loginInfo.Login.LoginProvider;
                //return View("ExternalLoginConfirmation", new ExternalLoginConfirmationViewModel { UserName = loginInfo.DefaultUserName });
                return View("Index");
            }
            else
            {
                await SignInAsync(ciudadano, isPersistent: false);
                return RedirectToLocal(returnUrl);
            }
        }

        protected override void Dispose(bool disposing)
        {
            if (disposing && UserManager != null)
            {
                UserManager.Dispose();
                UserManager = null;
            }

            base.Dispose(disposing);
        }




        #region Helpers
        // Used for XSRF protection when adding external logins
        private const string XsrfKey = "XsrfId";

        private IAuthenticationManager AuthenticationManager
        {
            get
            {
                return HttpContextFactory.GetHttpContext().GetOwinContext().Authentication;
                // HttpContext.GetOwinContext().Authentication;
            }
        }

        private async Task SignInAsync(Ciudadano ciudadano, bool isPersistent)
        {
            AuthenticationManager.SignOut(DefaultAuthenticationTypes.ExternalCookie);
            var identity = await UserManager.CreateIdentityAsync(ciudadano, DefaultAuthenticationTypes.ApplicationCookie);
            AuthenticationManager.SignIn(new AuthenticationProperties() { IsPersistent = isPersistent }, identity);
        }

        private ActionResult RedirectToLocal(string returnUrl)
        {
            if (Url.IsLocalUrl(returnUrl))
            {
                return Redirect(returnUrl);
            }
            else
            {
                return RedirectToAction("Index", "Home");
            }
        }

        private class ChallengeResult : HttpUnauthorizedResult
        {
            public ChallengeResult(string provider, string redirectUri)
                : this(provider, redirectUri, null)
            {
            }

            public ChallengeResult(string provider, string redirectUri, string userId)
            {
                LoginProvider = provider;
                RedirectUri = redirectUri;
                UserId = userId;
            }

            public string LoginProvider { get; set; }
            public string RedirectUri { get; set; }
            public string UserId { get; set; }

            public override void ExecuteResult(ControllerContext context)
            {
                var properties = new AuthenticationProperties() { RedirectUri = RedirectUri };

                if (UserId != null)
                    properties.Dictionary[XsrfKey] = UserId;

                HttpContextFactory.GetHttpContext().GetOwinContext().Authentication.Challenge(properties, LoginProvider);
            }

        #endregion
        }
	}
}